Qué es PL/SQL
PL/SQL es el lenguaje procedural de Oracle que combina SQL con estructuras de programación.
Permite ejecutar lógica directamente dentro del servidor Oracle.
Ventajas principales
- Reduce tráfico entre aplicación y servidor.
- Mejora rendimiento.
- Centraliza lógica crítica.
- Permite automatización.
- Aumenta seguridad.
PL/SQL vs SQL
| SQL | PL/SQL |
|---|---|
| Manipulación de datos | Lógica procedural |
| Consultas | Condiciones y bucles |
| Sin estructuras complejas | Variables y excepciones |
Estructuras disponibles
- IF
- ELSIF
- LOOP
- WHILE
- FOR
DECLARE · BEGIN · EXCEPTION · END
Todo bloque PL/SQL sigue una estructura clara.
DECLARE
-- Variables
BEGIN
-- Código principal
EXCEPTION
-- Manejo de errores
END;
DECLARE
Zona opcional para variables, constantes y cursores.
BEGIN
Parte principal del código.
EXCEPTION
Captura errores y evita interrupciones.
END
Final obligatorio del bloque.
Ejemplo completo
DECLARE
v_nombre VARCHAR2(50);
BEGIN
v_nombre := 'Carlos';
DBMS_OUTPUT.PUT_LINE(v_nombre);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error');
END;
Variables PL/SQL
PL/SQL permite trabajar con variables tipadas.
Tipos habituales
- VARCHAR2
- NUMBER
- DATE
- BOOLEAN
Declaración básica
DECLARE
v_nombre VARCHAR2(50);
v_edad NUMBER;
BEGIN
v_nombre := 'Laura';
v_edad := 28;
END;
%TYPE
Hereda automáticamente el tipo de una columna.
v_salario empleados.salario%TYPE;
Ventajas de %TYPE
- Evita incompatibilidades.
- Reduce errores.
- Facilita mantenimiento.
Empresa real: Randstad España
Randstad automatiza consultas internas mediante bloques PL/SQL.
Objetivo
- Consultar empleados rápidamente.
- Reducir errores.
- Automatizar reporting.
Bloque usado
DECLARE
v_nombre empleados.nombre%TYPE;
v_salario empleados.salario%TYPE;
BEGIN
SELECT nombre, salario
INTO v_nombre, v_salario
FROM empleados
WHERE id = 2;
DBMS_OUTPUT.PUT_LINE(
'Empleado: ' || v_nombre
);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE(
'Empleado no encontrado'
);
END;
Beneficios
- Consultas más rápidas.
- Menos errores humanos.
- Lógica centralizada.
Procedimientos y funciones en PL/SQL
Procedimientos
Realizan acciones pero no devuelven valor directo.
CREATE OR REPLACE PROCEDURE
mostrar_empleado(p_id IN NUMBER)
AS
v_nombre empleados.nombre%TYPE;
BEGIN
SELECT nombre
INTO v_nombre
FROM empleados
WHERE id = p_id;
DBMS_OUTPUT.PUT_LINE(v_nombre);
END;
Funciones
Devuelven un valor usando RETURN.
CREATE OR REPLACE FUNCTION
calcular_media
RETURN NUMBER IS
v_media NUMBER;
BEGIN
SELECT AVG(salario)
INTO v_media
FROM empleados;
RETURN v_media;
END;
Parámetros
| Tipo | Uso |
|---|---|
| IN | Entrada |
| OUT | Salida |
| IN OUT | Entrada y salida |
Manejo de excepciones
Las excepciones controlan errores sin detener procesos críticos.
Excepciones habituales
- NO_DATA_FOUND
- TOO_MANY_ROWS
- ZERO_DIVIDE
- WHEN OTHERS
Ejemplo
BEGIN
SELECT salario
INTO v_salario
FROM empleados
WHERE id = 99;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE(
'No existe'
);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(
SQLERRM
);
END;
SQLERRM
Devuelve el mensaje exacto del error.
Estrategia del Banco Santander
Banco Santander centraliza lógica crítica mediante funciones y procedimientos.
Función financiera
CREATE OR REPLACE FUNCTION
comision_promedio
RETURN NUMBER IS
v_avg NUMBER;
BEGIN
SELECT AVG(comision)
INTO v_avg
FROM ventas;
RETURN v_avg;
EXCEPTION
WHEN OTHERS THEN
RETURN 0;
END;
Ventajas
- Mayor rendimiento.
- Reglas centralizadas.
- Menos errores.
- Procesos reutilizables.
Paquetes (PACKAGES)
Un package agrupa procedimientos, funciones y variables relacionadas.
Ventajas
- Organización modular.
- Mejor rendimiento.
- Encapsulamiento.
- Escalabilidad.
Dos partes
| Parte | Descripción |
|---|---|
| Specification | Interfaz pública |
| Body | Implementación interna |
Ejemplo
CREATE OR REPLACE PACKAGE
gestion_nominas AS
PROCEDURE actualizar_salario;
FUNCTION obtener_media
RETURN NUMBER;
END;
Cómo se organizan los paquetes
Ejemplos típicos
- gestion_clientes
- gestion_nominas
- auditoria_operaciones
- gestion_stock
Buenas prácticas
- Agrupar lógica relacionada.
- Ocultar variables privadas.
- Separar interfaz e implementación.
- Documentar subprogramas.
Caching
Oracle mantiene packages cargados en memoria para mejorar velocidad.
Herramientas útiles
USER_OBJECTS
USER_ERRORS
ALL_SOURCE
Ejemplo explicado de código
Package completo
CREATE OR REPLACE PACKAGE
gestion_nominas AS
PROCEDURE actualizar_salario(
p_id NUMBER,
p_porcentaje NUMBER
);
FUNCTION obtener_media
RETURN NUMBER;
END gestion_nominas;
BODY
CREATE OR REPLACE PACKAGE BODY
gestion_nominas AS
PROCEDURE actualizar_salario(
p_id NUMBER,
p_porcentaje NUMBER
)
IS
BEGIN
UPDATE empleados
SET salario =
salario * (1 + p_porcentaje / 100)
WHERE id = p_id;
END;
FUNCTION obtener_media
RETURN NUMBER IS
v_media NUMBER;
BEGIN
SELECT AVG(salario)
INTO v_media
FROM empleados;
RETURN v_media;
END;
END gestion_nominas;
Análisis
- Specification define interfaz.
- BODY implementa lógica.
- UPDATE modifica salarios.
- AVG calcula media.
Optimización y buenas prácticas en PL/SQL
Problemas comunes
- Cursores innecesarios.
- Consultas dentro de bucles.
- Demasiados commits.
- Errores sin controlar.
BULK COLLECT
SELECT id, precio
BULK COLLECT INTO
v_ids, v_precios
FROM productos;
FORALL
FORALL i IN 1..v_ids.COUNT
UPDATE productos
SET precio = v_precios(i) * 1.05
WHERE id = v_ids(i);
Auditoría
CREATE TRIGGER auditar_precios
AFTER UPDATE ON productos
FOR EACH ROW
INSERT INTO log_precios
(id_producto, precio_anterior,
precio_nuevo, fecha)
VALUES
(:OLD.id,
:OLD.precio,
:NEW.precio,
SYSDATE);
Herramientas y consejos
Herramientas profesionales
- Oracle SQL Developer
- TOAD for Oracle
- Oracle LiveSQL
- PL/SQL Profiler
Consejos clave
- Documenta siempre.
- Usa módulos pequeños.
- Controla excepciones.
- Usa BULK COLLECT.
- Evita commits innecesarios.
- Centraliza auditoría.
Depuración
SHOW ERRORS;
SELECT * FROM USER_ERRORS;
Buenas prácticas de naming
| Prefijo | Uso |
|---|---|
| v_ | Variables |
| p_ | Parámetros |
| c_ | Constantes |